/**
 * iview 文件的上传到后台组件
 *
 * @author Zeon scplay@gmail.com
 * @date 2018/5/24
 * @copyright Created by Panxsoft.
 */
<!-- @example
  <Form-item
    label="店铺头像"
    prop="store_img">
    <IviewUploader
      :uploadLimitNum="1"
      :defaultFileList="[{'url': 'https://o5wwk8baw.qnssl.com/a42bdcc1178e62b4694c830f028db5c0/avatar'}]"
      :on-success="file=>fileChange(file,'store_img','image_info')"
      :on-remove="file=>fileRemove(file,'store_img')"
    />
  </Form-item>
-->
<style scoped lang="less">
  .upload-list{
    display: inline-block;
    width: 60px;
    height: 60px;
    text-align: center;
    line-height: 60px;
    border: 1px solid transparent;
    border-radius: 4px;
    background: #fff;
    position: relative;
    box-shadow: 0 1px 1px rgba(0,0,0,.2);
    margin-right: 4px;

    img{
      width: 100%;
      height: 100%;
    }

    .upload-list-cover{
      display: none;
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      background: rgba(0,0,0,.3);
      cursor: pointer;
      i {
        color: #fff;
        font-size: 20px;
        cursor: pointer;
        margin: 0 2px;
      }
    }

    &:hover .upload-list-cover{
      display: block;
    }

    .del-img-icon {
      position: absolute;
      right: 0;
      top: 0;
      transform: translate(50%, -50%);

      &.ivu-icon-ios-close:before {
        color: #ed3f14;
      }
    }
  }
</style>
<style lang="less">
  .v-comp-iview-uploader {
    .uploader {
      display: inline-block;width:58px;

      .upload-controller {
        width: 58px;
        height:58px;
        line-height: 62px;
      }

      .ivu-progress {
        position: absolute;
        top: 0;
        left: 0;
      }
    }
  }

  // this is fixed out of component, so it should has a Global identified Class
  .iv-upl-m-preview-image {
    width: 100%;
  }
</style>
<template>
	<div class="v-comp-iview-uploader">
		<!-- File/Image Preview List BEGIN -->
		<div
			v-for="(image, index) in uploadList"
			:key="index"
			class="upload-list">

			<template v-if="image.status === 'finished'">
				<img :src="image.url">
				<div
					class="upload-list-cover"
					@click.stop="showPreviewModal(image)">
					<Icon type="ios-eye-outline"/>
					<Icon
						class="del-img-icon"
						type="ios-close"
						@click.native.stop="delFile(image)"/>
				</div>
			</template>

			<template v-else>
				<Progress
					v-if="image.showProgress"
					:percent="image.percentage"
					hide-info/>
			</template>

		</div>
		<!-- File/Image Preview List END -->

		<!-- Uploader BEGIN -->
		<!-- @link https://www.iviewui.com/components/upload -->
		<Upload
			v-show="showUploadIcon"
			ref="upload"
			:name="postFileName"
			:show-upload-list="false"
			:default-file-list="defaultFileList"
			:on-success="handleUploadResponse"
			:on-error="onError"
			:format="format"
			:max-size="maxSize"
			:on-format-error="onFormatError"
			:on-exceeded-size="onExceededSize"
			:before-upload="beforeUpload"
			:multiple="multiple"
			:data="data"
			:action="action"
			class="uploader"
			type="drag">

			<!-- Uploader Icon BEGIN -->
			<div class="upload-controller">
				<Icon
					type="ios-cloud-upload"
					size="20"/>
			</div>
			<!-- Uploader Icon END -->

		</Upload>
		<!-- Uploader END -->

		<!-- Image Viewer Modal BEGIN -->
		<Modal
			v-model="previewModalShow"
			:title="this.$t('iview_uploader.show_pic')">
			<img
				v-if="previewModalShow"
				:src="previewSrc"
				class="iv-upl-m-preview-image">
		</Modal>
		<!-- Image Viewer Model END -->
	</div>
</template>
<script>
const SERVICE_IVIEW_FILE = '/api/admin/service/iview-file';

export default {
	name: 'IviewUploader',
	props: {
		defaultFileList: {
			type: Array,
			default() {
				return [
					// {
					//   'url': 'https://o5wwk8baw.qnssl.com/a42bdcc1178e62b4694c830f028db5c0/avatar'
					// },
				];
			},
			validator(list) {
				if (!(list instanceof Array)) {
					return false;
				}

				return list.every(file => file.url);
			},
			required: false,
		},

		/**
       * Post Extra Data
       */
		data: {
			type: Object,
			default() {
				return {
					bos_dir: 'misc/upload-test/',
				};
			},
			required: false,
		},

		uploadLimitNum: {
			required: false,
			type: Number,
			default: 1,
		},

		format: {
			type: Array,
			default() {
				return ['jpg', 'jpeg', 'png'];
			},
			required: false,
		},

		maxSize: {
			required: false,
			type: Number,
			default: 2048,
		},

		action: {
			required: false,
			type: String,
			default: SERVICE_IVIEW_FILE,
		},

		onSuccess: {
			required: false,
			type: Function,
			default() {
				return () => {};
			},
		},

		onRemove: {
			required: false,
			type: Function,
			default() {
				return () => {};
			},
		},

		onError: {
			required: false,
			type: Function,
			default() {
				return this.handleUploadError;
			},
		},

		onFormatError: {
			required: false,
			type: Function,
			default() {
				return this.handleFormatError;
			},
		},

		onExceededSize: {
			required: false,
			type: Function,
			default() {
				return this.handleExceedSize;
			},
		},

		/**
       * 当 Multi 是 true 是，请自己判断上传限制条件与错误提示
       */
		beforeUpload: {
			required: false,
			type: Function,
			default() {
				return this.handleBeforeUpload;
			},
		},

	},
	data() {
		return {
			uploadList: [],
			previewModalShow: false,
			multiple: false,
			previewSrc: '',
			postFileName: 'file',
		};
	},
	computed: {
		showUploadIcon() {
			return this.uploadLimitNum > this.uploadList.length;
		},
	},

	mounted() {
		this.uploadList = this.$refs.upload.fileList;
	},
	methods: {
		showPreviewModal(image) {
			this.previewSrc = image.url;
			this.previewModalShow = true;
		},

		delFile(file) {
			const { fileList } = this.$refs.upload;

			this.$refs.upload.fileList.splice(fileList.indexOf(file), 1);

			// DO Not Use $http.delete , it cannot add params
			if (this.$http) {
				this.$http.post(SERVICE_IVIEW_FILE, {
					url: file.url,
					_method: 'DELETE',
				});
			}

			this.onRemove(file);
		},

		/**
       * 处理上传文件响应
       */
		handleUploadResponse(res, file) {
			if (typeof res !== 'object') {
				this.uploadList.pop();
				return this.handleUploadError(new Error(this.$t('iview_uploader.upload_error_tip'))); // '上传失败，返回值格式错误'
			}

			if (res.code !== 0) {
				this.uploadList.pop();
				return this.handleUploadError(new Error(res.error));
			}

			file.url = res.url;

			this.onSuccess(file);
		},

		/**
       * 处理上传文件失败
       */
		handleUploadError(err) {
			this.$Notice.warning({
				title: this.$t('iview_uploader.upload_fail'), // '上传文件失败',
				desc: err,
			});
		},

		/**
       * 文件格式错误
       */
		handleFormatError(file) {
			this.$Notice.warning({
				title: this.$t('iview_uploader.format_error'), // '上传文件格式错误',
				desc: this.$t('iview_uploader.format_error_desc', { field: file.name }), // `文件：${}，格式非 jpg 或 png`,
			});
		},

		/**
       * 文件格式错误
       */
		handleExceedSize(file) {
			this.$Notice.warning({
				title: this.$t('iview_uploader.size_error'), // '上传文件大小超出限制',
				desc: this.$t('iview_uploader.size_error_desc', { field: file.name }), //  `文件：${file.name} 尺寸超过 2M 限制.`,
			});
		},

		/**
       * 上传前处理图片
       *
       * @return {boolean}
       */
		handleBeforeUpload() {
			const canUpload = this.uploadList.length < this.uploadLimitNum;
			if (!canUpload) {
				this.$Notice.warning({
					title: this.$t('iview_uploader.limit_error', { number: this.uploadLimitNum }), // `最多上传${this.uploadLimitNum}个文件.`,
				});
			}
			return canUpload;
		},

		/**
		 * 清空
		 */
		clearFiles() {
			this.$refs.upload.fileList.forEach(item => this.delFile(item));
		},
	},
};
</script>
